package com.daiqee.service.impl;

import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.daiqee.pojo.GoodsList;
import com.daiqee.pojo.StockIn;
import com.daiqee.dao.mapper.StockInMapper;
import com.daiqee.util.MyBatisPlusUtils;

/**
 * 入库
 * 
 * <br/>
 * @since JDK 1.8
 * @version  V2.1
 * @author RichardTang 
 * @date: 2018年5月8日 上午8:27:24
 * @package com.daiqee.service.impl
 * @copyright:Copyright (c) 2018, 1245811923@qq.com All Rights Reserved.
 */
@Service
public class StockInService extends ServiceImpl<StockInMapper, StockIn>{

	int resultNum = 0;
	
	boolean isNormalFinish = false;
	
	@Autowired
	private StockInMapper stockInMapper;
	
	@Autowired
	private GoodsListService goodsListService; 
	
	/**
	 * 添加 入库单 和 货物添加到货物清单表
	 * 
	 * @param array 
	 * 			货物
	 * 
	 * @param obj
	 * 			入库单
	 * 
	 * @return boolean
	 * 		
	 */
	public Boolean addGoodsListAndStockIn(List<GoodsList> goodsList, StockIn orderInfo) {
		
		//设置订单入库时间
		orderInfo.setStockInInputTime(new Date());
		
		//设置入库单号
		orderInfo.setStockInOrderNumber(MyBatisPlusUtils.getInOrderNumber());
		
		//添加货物单号
		stockInMapper.insert(orderInfo);
		
		//存储当前需要被添加的货物的货物名称
		ArrayList<String> goodsName = new ArrayList<String>();
		
		//设置货物的信息
		for (GoodsList goods : goodsList) {
			//拿到货物名称
			goodsName.add(goods.getGoodsListProductName());
			//设置出库的总数
			goods.setGoodsListOutStockCount(goods.getGoodsListProductAmount());
			//给货物设置入库状态
			goods.setGoodsListInStockStatus(orderInfo.getStockInStatus());
			//设置入库id
			goods.setGoodsListInStockId(orderInfo.getStockInId());
			//设置货物入库时间
			goods.setGoodsListInStockTime(new Date());
		}
		
		//判断当前录入的单子,是否是已经入库完成的状态
		if(orderInfo.getStockInStatus().equals("入库完成")) {
			//调用方法进行数据拆分
			Map<String,ArrayList<GoodsList>> resultMap = combinedGoods(goodsList);
			//取出两个集合
			ArrayList<GoodsList> updateArrayList = resultMap.get("update");
			ArrayList<GoodsList> insertArrayList = resultMap.get("insert");
			
			if(!updateArrayList.isEmpty())
				isNormalFinish = goodsListService.updateBatchById(updateArrayList);
			if(!insertArrayList.isEmpty())
				isNormalFinish = goodsListService.insertBatch(insertArrayList);
		}else {
			//不是入库完成状态,就直接添加.
			isNormalFinish = goodsListService.insertBatch(goodsList);
		}
		
		return isNormalFinish;
	}

	/**
	 * 删除入库单 和 更新货物清单
	 * 
	 * @param ids
	 * 			需要删除的id
	 * 
	 * @param goods
	 * 			更新的参数
	 */
	public Boolean removeStockInOrder(List<String> ids,GoodsList goods){
		
		//根据id批量删除入库单
		resultNum = stockInMapper.deleteBatchIds(ids);
		
		//查询条件
		Wrapper<GoodsList> ew = new EntityWrapper<GoodsList>().in("goods_list_in_stock_id", ids);
		
		//存在货物在进行货物的更新,不存在仅删除出库单即可
		Integer tempCount = goodsListService.selectCount(ew);
		
		//在删除之前先判断是否存在货物
		if(tempCount > 0) {
			//先更新货物
			isNormalFinish = goodsListService.update(goods,ew);
		}
		
		return isNormalFinish && resultNum > 0;
	}

	/**
	 * 更新入库单信息
	 * 
	 * @param array 
	 * 			货物
	 * 
	 * @param obj
	 * 			入库单
	 * 
	 * @return boolean
	 * 
	 * @throws Exception 
	 * 		
	 */
	public Boolean updateGoodsListAndStockIn(List<GoodsList> array, StockIn obj,
			List<String> remIds,String author) throws Exception {
		
		stockInMapper.updateById(obj);
		
		//存储需要更新的货物的id
		ArrayList<Integer> goodsIds = new ArrayList<Integer>();
		
		
		for (GoodsList goodsList : array) {
			
			//存储id
			goodsIds.add(goodsList.getGoodsListProductId());
			
			goodsList.setGoodsListOutStockCount(goodsList.getGoodsListProductAmount());
			
			//更新入库状态
			goodsList.setGoodsListInStockStatus(obj.getStockInStatus());
			
			//设置入库id
			goodsList.setGoodsListInStockId(obj.getStockInId());
			
		}
		
		//如果货物有被删除着更新货物的log
		if(remIds != null && remIds.size() > 0) {
			
			GoodsList goods = new GoodsList();
			
			goods.setGoodsListOutStockCount(goods.getGoodsListProductAmount());
			
			//设置入库单id号
			goods.setGoodsListInStockId(obj.getStockInId());
			
			//设置是否有入库单标记
			goods.setGoodsListInFlag("N");
			
			//设置入库状态
			goods.setGoodsListInStockStatus("无");
			
			//设置逻辑删除
			goods.setDeleteFlag("Y");
			
			goods.setGoodsListOperatLog(
		        new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(new Date())+
		        ",该货物在修改对应的入库单时移除-操作用户:"+author
			);
			
			isNormalFinish = goodsListService.update(goods, 
					new EntityWrapper<GoodsList>().in("goods_list_product_id",remIds)
			);
			
			if (!isNormalFinish) {
				throw new Exception("更新删除的货物失败!");
			}
			
		}
		
		//入库完成,将货物合并
		if(obj.getStockInStatus().equals("入库完成")) {
			//调用方法进行数据拆分
			Map<String,ArrayList<GoodsList>> resultMap = combinedGoods(array);
			//取出两个集合
			ArrayList<GoodsList> updateArrayList = resultMap.get("update");
			ArrayList<GoodsList> insertArrayList = resultMap.get("insert");
			
			if(!updateArrayList.isEmpty())
				isNormalFinish = goodsListService.updateBatchById(updateArrayList);
			if(!insertArrayList.isEmpty())
				isNormalFinish = goodsListService.insertBatch(insertArrayList);
			
			//更新完成后还需要删除旧的货物数据
			goodsListService.deleteBatchIds(goodsIds);
			
		}else {
			isNormalFinish = goodsListService.insertOrUpdateBatch(array);
		}
		
		return isNormalFinish;
	}
	
	
	/**
	 * 合并货物,将添加的货物和已存在的货物进行数据合并
	 * @param resultMap
	 * 			update:需要更新的数据集合
	 * 			insert:需要插入的数据集合
	 */
	public Map<String,ArrayList<GoodsList>> combinedGoods(List<GoodsList> goodsList){

		//用来存放两个集合Map
		HashMap<String,ArrayList<GoodsList>> resultMap = new HashMap<String,ArrayList<GoodsList>>();
		
		//需要更新的货物
		ArrayList<GoodsList> needUpdate = new ArrayList<GoodsList>();
		
		//需要插入的货物
		ArrayList<GoodsList> needInsert = new ArrayList<GoodsList>();
		
		//需要判断的货物名称
		ArrayList<String> productNames = new ArrayList<String>();

		resultMap.put("update", needUpdate);
		resultMap.put("insert", needInsert);
		
		//取出名称
		for(GoodsList goods : goodsList) {
			//拿到名称,然后添加到集合
			productNames.add(goods.getGoodsListProductName());
		}
		
		//根据名称来判断是否存在该货物类型
		EntityWrapper<GoodsList> ew = (EntityWrapper<GoodsList>) new EntityWrapper<GoodsList>().in("goods_list_product_name", productNames);
		
		//设置查询的数据必须是入库完成的状态
		ew.eq("goods_list_in_stock_status", "入库完成");
		//并且还必须是未出库状态
		ew.eq("goods_list_out_flag", "N");
		
		//查询出这些货物
		List<GoodsList> haveOfGoods = goodsListService.selectList(ew);
		
		Map<String,GoodsList> goodsMap = new HashMap<String,GoodsList>();
		
		//将List转换成Map,使用货物名称作为Key
		for (GoodsList haveGoods : haveOfGoods) {
			goodsMap.put(haveGoods.getGoodsListProductName(), haveGoods);
		}
		
		//判断需要添加的货物中是否存在重复的货物
		for(int item = 0;item < goodsList.size();item++) {
			
			//拿到当前循环到的货物
			GoodsList currentGoods = goodsList.get(item);
			
			//使用需要被添加的货物的货物名称,来当key,从map中取值,判断之前时候已存在该货物
			GoodsList addedGoods = goodsMap.get(currentGoods.getGoodsListProductName());
			
			//不等于NULL代表是存在货物
			if(addedGoods != null) {
				//设置id-给当前需要添加进来的货物
				currentGoods.setGoodsListProductId(addedGoods.getGoodsListProductId());
				
				//货物之前已存在,覆盖原来的值
				currentGoods.setGoodsListProductAmount(
						//原先货物数量+当前需要存入的数量
						addedGoods.getGoodsListProductAmount() + currentGoods.getGoodsListProductAmount()
				);
				//设置入库时间
				currentGoods.getGoodsListInStockTime();
				
				//这个是需要被更新的数据
				needUpdate.add(currentGoods);
			}else {
				//需要被添加的数据
				needInsert.add(currentGoods);
			}
		}
		
		return resultMap;
	}
}
